<?php
/**
 * phpDocumentor
 *
 * PHP Version 5.3
 *
 * @author    Mike van Riel <mike.vanriel@naenius.com>
 * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
 * @link      http://phpdoc.org
 */
namespace phpDocumentor\Command\Template;

use \Symfony\Component\Console\Input\InputInterface;
use \Symfony\Component\Console\Input\InputOption;
use \Symfony\Component\Console\Output\OutputInterface;

/**
 * Generates a packages the template into a PEAR package.
 */
class PackageCommand extends \Cilex\Command\Command
{
    /**
     * Initializes this command and sets the name, description, options and
     * arguments.
     *
     * @return void
     */
    protected function configure()
    {
        $this->setName('template:package')
            ->setDescription(
                'Packages a template for distribution'
            )
            ->setHelp(
<<<HELP
Packages a template so that it can be distributed by the phpdocumentor
PEAR channel.

This task accepts 2 arguments:

* The path to the template source files
* The short name for this template; this must be unique in phpDocumentor's
  repository.

This task depends on PEAR's PEAR_PackageFileManager2 package.
HELP
            )
            ->addOption(
                'debug',
                null,
                InputOption::VALUE_NONE,
                'Outputs the package\'s XML rather than generate it.'
            );

    }

    /**
     * Executes the business logic involved with this command.
     *
     * @param InputInterface  $input
     * @param OutputInterface $output
     *
     * @return int
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        error_reporting(E_ALL & ~E_STRICT & ~E_DEPRECATED);
        if (!@include 'PEAR/PackageFileManager2.php') {
            throw new \Exception('Unable to find the PEAR_PackageFileManager2 package, is it installed?');
        }
        \PEAR::setErrorHandling(PEAR_ERROR_DIE);

        $args = $this->getRemainingArgs();
        if (!isset($args[1])) {
            throw new \Exception('Missing path to the template source');
        }
        if (!isset($args[2])) {
            throw new \Exception('Missing the template name');
        }

        $path     = $args[1];
        $template = $args[2];

        if (!preg_match('/^[a-z\d][a-z_\d]{2,}$/', $template)) {
            throw new \Exception(
                'A template name may only consist of lowercase letters, digits and'
                .' underscores; may not start with an underscore and consist of '
                .'at least 3 characters.'
            );
        }

        if (!file_exists($path . '/template.xml') || !is_readable($path . '/template.xml')
        ) {
            throw new \Exception('Template definition (' . $path . '/template.xml) was not found or is unreadable.');
        }

        $settings    = simplexml_load_file($path . '/template.xml');
        $version     = (string)$settings->version;
        $author      = (string)$settings->author;
        $description = (string)$settings->description;
        $email       = (string)$settings->email;

        // merge the options with these defaults.
        $options = array(
            'packagefile' => 'package.xml',
            'filelistgenerator' => 'file',
            'simpleoutput' => true,
            'baseinstalldir' => '/phpDocumentor/data/templates/' . $template,
            'packagedirectory' => $path,
            'clearcontents' => true,
            'ignore' => array(),
            'exceptions' => array(),
            'installexceptions' => array(),
            'dir_roles' => array(
                '/' => 'php', // explicitly set the role to php to allow the
                // templates to be installed inside the phpDocumentor PEAR folder.
                // This will help keep everything together
            ),
        );

        $packagexml = \PEAR_PackageFileManager2::importOptions('', $options);
        $packagexml->setPackageType('php');

        $packagexml->setPackage('phpDocumentor_Template_' . $template);
        $packagexml->setSummary('The ' . $template . ' template for phpDocumentor');
        $packagexml->setDescription($description);
        $packagexml->setChannel('pear.phpdoc.org');
        $packagexml->setNotes('Automatically generated by the phpDocumentor packager');

        $packagexml->setPhpDep('5.2.6');
        $packagexml->setPearinstallerDep('1.4.0');
        $packagexml->addPackageDepWithChannel('required', 'PEAR', 'pear.php.net', '1.4.0');
        $packagexml->addPackageDepWithChannel('required', 'phpDocumentor', 'pear.phpdoc.org', '0.17.0');

        if ($settings->dependencies->template) {
            foreach ($settings->dependencies->template as $dependency) {
                $dependency_name    = (string)$dependency['name'];
                $dependency_version = (string)$dependency['version'];
                $packagexml->addPackageDepWithChannel(
                    'required',
                    'phpDocumentor_Template_'. $dependency_name,
                    'pear.phpdoc.org',
                    $dependency_version
                );
            }
        }

        $packagexml->addMaintainer('lead', '', $author, $email);
        $packagexml->setLicense('MIT', 'http://www.opensource.org/licenses/mit-license.html');

        // Add this as a release, and generate XML content
        $packagexml->addRelease();

        $packagexml->setAPIVersion($version);
        $packagexml->setReleaseVersion($version);
        $packagexml->setReleaseStability('stable');
        $packagexml->setAPIStability('stable');

        $packagexml->generateContents();
        if ($this->getDebug()) {
            $packagexml->debugPackageFile();
            return;
        }

        $packagexml->writePackageFile();
        passthru('pear package '.$path.'/package.xml');

        return 0;
    }
}
